package com.itheima.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.mapper.EmpMapper;
import com.itheima.pojo.*;
import com.itheima.service.DeptService;
import com.itheima.service.EmpExprService;
import com.itheima.service.EmpService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

@Service
@Slf4j
public class EmpServiceImpl  extends ServiceImpl<EmpMapper, Emp> implements EmpService {


    @Resource
    private DeptService deptService;

    @Resource
    private EmpExprService empExprService;

    /**
     * 分页查询员工列表
     * 1.先准备实体类：要有一个属性deptName用于封装部门名称，且没有对应的数据库字段
     * 2.分页查询员工列表： Service类继承来了分页查询的方法pageXxx
     * @param param
     * @return
     */
    @Override
    public PageResult<Emp> empPageResult(EmpQueryParam param) {
        //准备一下分页条件：用MP提供的IPage接口实现类  Page,
        //封装分页条件(页码  每页几条)
        //先准备Page对象/*  实际上是实例一父类 是IPage类型接口的对象*/
        Page<Emp> p = Page.of(param.getPage(), param.getPageSize());

        //增加排序条件
        p.addOrder(OrderItem.desc("entry_date"));

        //分页搜索条件
        LambdaQueryWrapper<Emp> wrapper  = Wrappers.<Emp>lambdaQuery()
                .like(param.getName()!=null && !"".equals(param.getName()), Emp::getName, param.getName())
                .eq(param.getGender()!=null, Emp::getGender, param.getGender())
                .between(param.getBegin()!=null && param.getEnd()!=null, Emp::getEntryDate, param.getBegin(), param.getEnd());


        //调用service继承来的page方法俩实现分页查询方法 ，返回的几个是Page对象
        /*  执行SQL语句时 拦截器（就是配置的MybatisConfig中mybatisPlusInterceptor）自动将原始SQL改写为物理分页SQL：
        *    同时自动生成COUNT查询 */
        p = page(p,wrapper);
        //获取查询的总数量
        long total = p.getTotal();
        //获取查询的员工列表集合
        List<Emp> empList = p.getRecords();

        //根据员工表中的deptId 获取部门表对应的名称
        //1.先将查询出的所有的员工的deptid 去重存放到一个集合
        Set<Integer> deptIds = empList.stream()
                .map(emp -> emp.getDeptId()).collect(Collectors.toSet());

        if (deptIds != null && !deptIds.isEmpty()) {
            //2.根据deptIds集合取部门表查找对应的名称
            List<Dept> deptList = deptService.listByIds(deptIds);

            //3.将 部门对象集合中的部门Id和部门名称转换成一个map集合
            Map<Integer, String> deptMap = deptList.stream()
                    .collect(Collectors.toMap(Dept::getId, Dept::getName));
            //循环每个员工,直接为每个员工的deptName赋值
            for (Emp emp : empList) {
                Integer deptId = emp.getDeptId();
                emp.setDeptName(deptMap.get(deptId));
            }
        }

        return new PageResult<>(total,empList);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void addEmp(Emp emp) {
        //创建和更新时间设置当前
        emp.setCreateTime(LocalDateTime.now());
        emp.setUpdateTime(LocalDateTime.now());
        //新增员工
        save(emp);

        //获取工作经历
        List<EmpExpr> exprList = emp.getExprList();
        //判断工作经历是否存在
        if (exprList == null || exprList.isEmpty()) {
            return;
        }
        //遍历工作经历，给员工id赋值
        for (EmpExpr empExpr : exprList) {
            empExpr.setEmpId(emp.getId());
        }

        //新增工作经历
        empExprService.saveBatch(exprList);




    }

    @Override
    public Emp getEmpById(Integer id) {

        //查询员工
        Emp emp = getById(id);

        //创建一个lambdaQueryWrapper对象
        LambdaQueryWrapper<EmpExpr> wrapper = Wrappers.<EmpExpr>lambdaQuery()
                .eq(EmpExpr::getEmpId, id);

        //查询员工id绑定的工作经历
        List<EmpExpr> list = empExprService.list(wrapper);

        //赋值到emp的exprList属性上
        emp.setExprList(list);

        return emp;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateEmpById(Emp emp) {
        log.info("更新前emp数据{}",emp);
        //更新时间为当前时间
        emp.setUpdateTime(LocalDateTime.now());

        //修改员工
        updateById(emp);


        LambdaQueryWrapper<EmpExpr> wrapper = Wrappers.<EmpExpr>lambdaQuery()
                .eq(EmpExpr::getEmpId, emp.getId());

        //删除工作经历
        empExprService.remove(wrapper);


        List<EmpExpr> exprList = emp.getExprList();
        //判断工作经历集合是否为空
        if (exprList != null && !exprList.isEmpty()) {
            //遍历工作经历，给每个工作经历绑定的员工id重新赋值，防止有新增的工作经历没有绑定工作经历
            for (EmpExpr empExpr : exprList) {
               empExpr.setEmpId(emp.getId());
            }
        }

        //插入新的工作经历
        empExprService.saveBatch(exprList);

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteEmpByIds(List<Integer> ids) {

        //删除员工
        removeByIds(ids);



        //过滤条件员工id in（ids）
        LambdaQueryWrapper<EmpExpr> wrapper = Wrappers.<EmpExpr>lambdaQuery()
                .in(EmpExpr::getEmpId, ids);

        //删除工作经历
        empExprService.remove(wrapper);

    }
}
